Help for defaults files.
40c9c469N2-b3GqpLHHHPZykJPLVvA tools/python/xen/xend/server/channel.py
40c9c469hJ_IlatRne-9QEa0-wlquw tools/python/xen/xend/server/console.py
40c9c469UcNJh_NuLU0ytorM0Lk5Ow tools/python/xen/xend/server/controller.py
-40c9c469vHh-qLiiubdbKEQbJf18Zw tools/python/xen/xend/server/cstruct.py
40d83983OXjt-y3HjSCcuoPp9rzvmw tools/python/xen/xend/server/domain.py
40c9c469yrm31i60pGKslTi2Zgpotg tools/python/xen/xend/server/messages.py
40c9c46925x-Rjb0Cv2f1-l2jZrPYg tools/python/xen/xend/server/netif.py
40c9c469LNxLVizOUpOjEaTKKCm8Aw tools/python/xen/xend/sxp.py
40d05079aFRp6NQdo5wIh5Ly31c0cg tools/python/xen/xm/__init__.py
40cf2937gKQcATgXKGtNeWb1PDH5nA tools/python/xen/xm/create.py
+40e41cd2w0I4En6qrJn4em8HkK_oxQ tools/python/xen/xm/help.py
40cf2937isyS250zyd0Q2GuEDoNXfQ tools/python/xen/xm/main.py
40cf2937PSslwBliN1g7ofDy2H_RhA tools/python/xen/xm/opts.py
40cf2937Z8WCNOnO2FcWdubvEAF9QQ tools/python/xen/xm/shutdown.py
#============================================================================
# Python defaults setup for 'xm create'.
# Edit this file to reflect the configuration of your system.
-# This file expects the variable 'vmid' to be set.
-#============================================================================
-
-try:
- vmid = int(vmid) # convert to integer
-except:
- raise ValueError, "Variable 'vmid' must be an integer"
-if vmid <= 0:
- raise ValueError, "Variable 'vmid' must be greater than 0"
+#============================================================================
+# Define script variables here.
+# xm_vars is defined automatically, use xm_vars.var() to define a variable.
+
+def vmid_check(var, val):
+ val = int(val)
+ if val <= 0:
+ raise ValueError
+ return val
+
+xm_vars.var('vmid',
+ use="Virtual machine id. Integer greater than 0.",
+ check=vmid_check)
+
+# This checks the script variables.
+xm_vars.check()
#----------------------------------------------------------------------------
# Kernel image file.
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
"""Client API for the HTTP interface on xend.
Callable as a script - see main().
+
+This API is the 'control-plane' for xend.
+The 'data-plane' is done separately. For example, consoles
+are accessed via sockets on xend, but the list of consoles
+is accessible via this API.
"""
import sys
import httplib
def sxprio(sxpr):
+ """Convert an sxpr to a string.
+ """
io = StringIO()
sxp.show(sxpr, out=io)
print >> io
return urljoin(location, root, 'event/', id)
def xend_request(url, method, data=None):
+ """Make a request to xend.
+
+ url xend request url
+ method http method: POST or GET
+ data request argument data (dict)
+ """
urlinfo = urlparse.urlparse(url)
(uproto, ulocation, upath, uparam, uquery, ufrag) = urlinfo
if DEBUG: print url, urlinfo
return val
def xend_get(url, args=None):
+ """Make a xend request using GET.
+ Requests using GET are 'safe' and may be repeated without
+ nasty side-effects.
+ """
return xend_request(url, "GET", args)
def xend_call(url, data):
+ """Make xend request using POST.
+ Requests using POST potentially cause side-effects and should
+ not be repeated unless it really is wanted to do the side
+ effect again.
+ """
return xend_request(url, "POST", data)
class Xend:
+ """Default location of the xend server."""
SRV_DEFAULT = "localhost:8000"
+
+ """Default path to the xend root on the server."""
ROOT_DEFAULT = "/xend/"
def __init__(self, srv=None, root=None):
self.bind(srv, root)
def bind(self, srv=None, root=None):
+ """Bind to a given server.
+
+ srv server location (host:port)
+ root server xend root path
+ """
if srv is None: srv = self.SRV_DEFAULT
if root is None: root = self.ROOT_DEFAULT
if not root.endswith('/'): root += '/'
+++ /dev/null
-import struct
-
-class Struct:
-
- maxDepth = 10
-
- base = ['x', 'B', 'H', 'I', 'L', 'Q', 'c', 'h', 'i', 'l', 'q', ]
-
- sizes = {'B': 1,
- 'H': 2,
- 'I': 4,
- 'L': 4,
- 'Q': 8,
- 'c': 1,
- 'h': 2,
- 'i': 4,
- 'l': 4,
- 'q': 8,
- 'x': 1,
- }
-
- formats = {
- 'int8' : 'B',
- 'int16' : 'H',
- 'int32' : 'I',
- 'int64' : 'Q',
- 'u8' : 'B',
- 'u16' : 'H',
- 'u32' : 'I',
- 'u64' : 'Q'
- }
-
- def typedef(self, name, val):
- self.formats[name] = val
-
- def struct(self, name, *f):
- self.typedef(name, StructInfo(self, f))
-
- def getType(self, name):
- return self.formats[name]
-
- def format(self, ty):
- d = 0
- f = ty
- while d < self.maxDepth:
- d += 1
- f = self.formats[f]
- if isinstance(f, StructInfo):
- return f.format()
- if f in self.base:
- return f
- return -1
-
- def alignedformat(self, ty):
- fmt = self.format(ty)
- #print 'alignedformat> %s |%s|' %(ty, fmt)
- afmt = self.align(fmt)
- #print 'alignedformat< %s |%s| |%s|' % (ty, fmt, afmt)
- return afmt
-
- def align(self, fmt):
- n1 = 0
- afmt = ''
- for a in fmt:
- n2 = self.getSize(a)
- m = n1 % n2
- if m:
- d = (n2 - m)
- afmt += 'x' * d
- n1 += d
- afmt += a
- n1 += n2
- return afmt
-
- def fmtsize(self, fmt):
- s = 0
- for f in fmt:
- s += self.getSize(f)
- return s
-
- def getSize(self, f):
- return self.sizes[f]
-
- def pack(self, ty, data):
- return self.getType(ty).pack(data)
-
- def unpack(self, ty, data):
- return self.getType(ty).unpack(data)
-
- def show(self):
- l = self.formats.keys()
- l.sort()
- for v in l:
- print "%-35s %-10s %s" % (v, self.format(v), self.alignedformat(v))
-
-
-class StructInfo:
-
- def __init__(self, s, f):
- self.fmt = None
- self.structs = s
- self.fields = f
-
- def alignedformat(self):
- if self.afmt: return self.afmt
- self.afmt = self.structs.align(self.format())
- return self.afmt
-
- def format(self):
- if self.fmt: return self.fmt
- fmt = ""
- for (ty, name) in self.fields:
- fmt += self.formatString(ty)
- self.fmt = fmt
- return fmt
-
- def formatString(self, ty):
- if ty in self.fields:
- ty = self.fields[ty]
- return self.structs.format(ty)
-
- def pack(self, *args):
- return struct.pack(self.alignedformat(), *args)
-
- def unpack(self, data):
- return struct.unpack(self.alignedformat(), data)
-
-types = Struct()
-
-types.typedef('short' , 'h')
-types.typedef('int' , 'i')
-types.typedef('long' , 'l')
-types.typedef('unsigned short', 'H')
-types.typedef('unsigned int' , 'I')
-types.typedef('unsigned long' , 'L')
-types.typedef('domid_t' , 'u64')
-types.typedef('blkif_vdev_t' , 'u16')
-types.typedef('blkif_pdev_t' , 'u16')
-types.typedef('blkif_sector_t', 'u64')
-
-types.struct('u8[6]',
- ('u8', 'a1'),
- ('u8', 'a2'),
- ('u8', 'a3'),
- ('u8', 'a4'),
- ('u8', 'a5'),
- ('u8', 'a6'))
-
-types.struct('blkif_fe_interface_status_changed_t',
- ('unsigned int', 'handle'),
- ('unsigned int', 'status'),
- ('unsigned int', 'evtchn'))
-
-types.struct('blkif_fe_driver_status_changed_t',
- ('unsigned int', 'status'),
- ('unsigned int', 'nr_interfaces'))
-
-types.struct('blkif_fe_interface_connect_t',
- ('unsigned int' , 'handle'),
- ('unsigned long', 'shmem_frame'))
-
-types.struct('blkif_fe_interface_disconnect_t',
- ('unsigned int', 'handle'))
-
-types.struct('blkif_extent_t',
- ('blkif_pdev_t' , 'device'),
- ('blkif_sector_t', 'sector_start'),
- ('blkif_sector_t', 'sector_length'))
-
-types.struct('blkif_be_create_t',
- ('domid_t' , 'domid'),
- ('unsigned int', 'blkif_handle'),
- ('unsigned int', 'status'))
-
-types.struct('blkif_be_destroy_t',
- ('domid_t' , 'domid'),
- ('unsigned int', 'blkif_handle'),
- ('unsigned int', 'status'))
-
-types.struct('blkif_be_connect_t',
- ('domid_t' , 'domid'),
- ('unsigned int' , 'blkif_handle'),
- ('unsigned int' , 'evtchn'),
- ('unsigned long', 'shmem_frame'),
- ('unsigned int' , 'status'))
-
-types.struct('blkif_be_disconnect_t',
- ('domid_t' , 'domid'),
- ('unsigned int', 'blkif_handle'),
- ('unsigned int', 'status'))
-
-types.struct('blkif_be_vbd_create_t',
- ('domid_t' , 'domid'), #Q
- ('unsigned int', 'blkif_handle'), #I
- ('blkif_vdev_t', 'vdevice'), #H
- ('int' , 'readonly'), #i
- ('unsigned int', 'status')) #I
-
-types.struct('blkif_be_vbd_destroy_t',
- ('domid_t' , 'domid'),
- ('unsigned int', 'blkif_handle'),
- ('blkif_vdev_t', 'vdevice'),
- ('unsigned int', 'status'))
-
-types.struct('blkif_be_vbd_grow_t',
- ('domid_t' , 'domid'), #Q
- ('unsigned int' , 'blkif_handle'), #I
- ('blkif_vdev_t' , 'vdevice'), #H
- ('blkif_extent_t', 'extent'), #HQQ
- ('unsigned int' , 'status')) #I
-
-types.struct('blkif_be_vbd_shrink_t',
- ('domid_t' , 'domid'),
- ('unsigned int', 'blkif_handle'),
- ('blkif_vdev_t', 'vdevice'),
- ('unsigned int', 'status'))
-
-types.struct('blkif_be_driver_status_changed_t',
- ('unsigned int', 'status'),
- ('unsigned int', 'nr_interfaces'))
-
-types.struct('netif_fe_interface_status_changed_t',
- ('unsigned int', 'handle'),
- ('unsigned int', 'status'),
- ('unsigned int', 'evtchn'),
- ('u8[6]', 'mac'))
-
-types.struct('netif_fe_driver_status_changed_t',
- ('unsigned int', 'status'),
- ('unsigned int', 'nr_interfaces'))
-
-types.struct('netif_fe_interface_connect_t',
- ('unsigned int', 'handle'),
- ('unsigned long', 'tx_shmem_frame'),
- ('unsigned long', 'rx_shmem_frame'))
-
-types.struct('netif_fe_interface_disconnect_t',
- ('unsigned int', 'handle'))
-
-types.struct('netif_be_create_t',
- ('domid_t' , 'domid'),
- ('unsigned int', 'netif_handle'),
- ('u8[6]' , 'mac'),
- ('unsigned int', 'status'))
-
-types.struct('netif_be_destroy_t',
- ('domid_t' , 'domid'),
- ('unsigned int', 'netif_handle'),
- ('unsigned int', 'status'))
-
-types.struct('netif_be_connect_t',
- ('domid_t' , 'domid'),
- ('unsigned int' , 'netif_handle'),
- ('unsigned int' , 'evtchn'),
- ('unsigned long', 'tx_shmem_frame'),
- ('unsigned long', 'rx_shmem_frame'),
- ('unsigned int' , 'status'))
-
-types.struct('netif_be_disconnect_t',
- ('domid_t' , 'domid'),
- ('unsigned int', 'netif_handle'),
- ('unsigned int', 'status'))
-
-types.struct('netif_be_driver_status_changed_t',
- ('unsigned int', 'status'),
- ('unsigned int', 'nr_interfaces'))
-
-if 1 or __name__ == "__main__":
- types.show()
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
+
"""Domain creation.
"""
import string
gopts = Opts(use="""[options]
Create a domain.
+
+Domain creation parameters can be set by command-line switches, from
+a python configuration script or an SXP config file. See documentation
+for --defaults, --config. Configuration variables can be set using
+VAR=VAL on the command line. For example vmid=3 sets vmid to 3.
+
""")
gopts.opt('help', short='h',
fn=set_true, default=0,
use="Print this help.")
+gopts.opt('help_config',
+ fn=set_true, default=0,
+ use="Print help for configuration file.")
+
gopts.opt('quiet', short='q',
fn=set_true, default=0,
use="Quiet.")
gopts.opt('defaults', short='f', val='FILE',
fn=set_value, default='xmdefaults',
- use="Use the given default script.")
+ use="""Use the given Python defaults script.
+The defaults script is loaded after arguments have been processed.
+Each command-line option sets a configuration variable named after
+its long option name, and these variables are placed in the
+environment of the script before it is loaded.
+Variables for options that may be repeated have list values.
+Other variables can be set using VAR=VAL on the command line.
+
+After the script is loaded, option values that were not set on the
+command line are replaced by the values set in the script.
+""")
gopts.opt('config', short='F', val='FILE',
fn=set_value, default=None,
- use='Domain configuration to use (SXP).')
+ use="""Domain configuration to use (SXP).
+SXP is the underlying configuration format used by Xen.
+SXP configs can be hand-written or generated from Python defaults
+scripts, using the -n (dryrun) option to print the config.
+""")
gopts.opt('load', short='L', val='FILE',
fn=set_value, default=None,
use='Domain saved state to load.')
-gopts.opt('define', short='D', val='VAR=VAL',
- fn=set_var, default=None,
- use="""Set a variable before loading defaults, e.g. '-D vmid=3'
- to set vmid. May be repeated to set more thanone variable.""")
+#gopts.opt('define', short='D', val='VAR=VAL',
+# fn=set_var, default=None,
+# use="""Set a variable before loading defaults, e.g. '-D vmid=3'
+# to set vmid. May be repeated to set more than one variable.""")
gopts.opt('dryrun', short='n',
fn=set_true, default=0,
- use="Dry run - print the config but don't create the domain.")
+ use="""Dry run - print the config but don't create the domain.
+The defaults file is loaded and the SXP configuration is created and printed.
+""")
gopts.opt('name', short='N', val='NAME',
fn=set_value, default=None,
args = opts.parse(argv)
if opts.vals.help:
opts.usage()
+ if opts.vals.help or opts.vals.help_config:
+ opts.load_defaults(help=1)
+ if opts.vals.help or opts.vals.help_config:
return
+ # Process remaining args as config variables.
+ for arg in args:
+ if '=' in arg:
+ (var, val) = arg.strip().split('=')
+ gopts.setvar(var.strip(), val.strip())
if opts.vals.config:
pass
else:
--- /dev/null
+# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
+
+"""Variable definition and help support for Python defaults files.
+"""
+
+import sys
+
+class Vars:
+ """A set of configuration variables.
+ """
+
+ def __init__(self, name, help, env):
+ """Create a variable set.
+
+ name name of the defaults file
+ help help flag
+ env local environment
+ """
+ self.name = name
+ self.help = help
+ self.env = env
+ self.vars = []
+
+ def var(self, name, use=None, check=None):
+ """Define a configuration variable.
+ If provided, the check function will be called as check(var, val)
+ where var is the variable name and val is its value (string).
+ It should return a new value for the variable, or raise ValueError if
+ the value is not acceptable.
+
+ name variable name
+ use variable usage string
+ check variable check function
+ """
+ self.vars.append(Var(name, use, check))
+
+ def check(self):
+ """Execute the variable checks or print help, depending on the value
+ of the help flag passed to the constructor.
+ """
+ if self.help:
+ self.doHelp()
+ else:
+ for v in self.vars:
+ v.doCheck(self.env)
+
+ def doHelp(self, out=sys.stderr):
+ """Print help for the variables.
+ """
+ if self.vars:
+ print >>out, "\nConfiguration variables for %s:\n" % self.name
+ for v in self.vars:
+ v.doHelp(out)
+ print >>out
+
+class Var:
+ """A single variable.
+ """
+
+ def __init__(self, name, use, check):
+ """Create a variable.
+
+ name variable name
+ use variable use string
+ check variable value check function
+ """
+ self.name = name
+ self.use = use or ''
+ self.check = check
+
+ def doCheck(self, env):
+ """Execute the check and set the variable to the new value.
+ """
+ if not self.check: return
+ env[self.name] = self.check(self.name, env.get(self.name))
+
+ def doHelp(self, out):
+ """Print help for the variable.
+ """
+ print >>out, "%-12s" % self.name, self.use
+
+
import os.path
import sys
from getopt import getopt
+import socket
from xen.xend import PrettyPrint
from xen.xend import sxp
from xen.xend.XendClient import server
+from xen.xend.XendClient import main as xend_client_main
from xen.xm import create, shutdown
class Prog:
sys.exit(1)
def main(self, args):
+ try:
+ self.main_call(args)
+ except socket.error, ex:
+ print >>sys.stderr, ex
+ self.err("Error connecting to xend, is xend running?")
+
+ def main_call(self, args):
"""Main entry point. Dispatches to the progs.
"""
self.name = args[0]
xm.prog(ProgConsole)
+class ProgCall(Prog):
+ name = "call"
+ info = "Call xend api functions."
+
+ def help (self, args):
+ print "call fn argss..."
+ print """
+ Call a xend HTTP API function. The leading 'xend_' on the function
+can be omitted. See xen.xend.XendClient for the API functions.
+"""
+
+ def main(self, args):
+ xend_client_main(args)
+
+xm.prog(ProgCall)
+
def main(args):
xm.main(args)
for opt in self.options:
opt.show()
- def load_defaults(self):
+ def load_defaults(self, help=0):
"""Load a defaults script. Assumes these options set:
'path' search path
'default' script name
else:
p = self.vals.defaults
if os.path.exists(p):
- self.load(p)
+ self.load(p, help)
break
else:
self.err("Cannot open defaults file %s" % self.vals.defaults)
- def load(self, defaults, help=0):
+ def load(self, defaults, help):
"""Load a defaults file. Local variables in the file
are used to set options with the same names.
Variables are not used to set options that are already specified.
cmd = '\n'.join(["import sys",
"import os",
"import os.path",
- "import xen.util.ip",
+ "from xen.xm.help import Vars",
+ "from xen.util import ip",
"xm_file = '%s'" % defaults,
- "xm_help = %d" % help ])
+ "xm_help = %d" % help,
+ "xm_vars = Vars(xm_file, xm_help, locals())",
+ ])
exec cmd in globals, locals
- execfile(defaults, globals, locals)
+ try:
+ execfile(defaults, globals, locals)
+ except:
+ if not help: raise
if help: return
# Extract the values set by the script and set the corresponding
# options, if not set on the command line.